package com.credithc.signature.manager.controller.patch;

import com.alibaba.fastjson.JSONObject;
import com.credithc.baseserv.core.codes.CoreCodes;
import com.credithc.baseserv.core.message.Message;
import com.credithc.baseserv.core.message.MessageFactory;
import com.credithc.signature.common.mapper.SignatureLogMapper;
import com.credithc.signature.common.po.Channel;
import com.credithc.signature.common.po.SignatureLog;
import com.credithc.signature.common.po.SignatureLogExt;
import com.credithc.signature.common.ro.facade.RequestData;
import com.credithc.signature.common.ro.manager.RequestLogRo;
import com.credithc.signature.common.service.ChannelService;
import com.credithc.signature.common.service.SignatureLogExtService;
import com.credithc.signature.common.service.SignatureLogService;
import com.credithc.signature.common.utils.DateUtil;
import com.credithc.signature.common.utils.HttpClientProxy;
import com.credithc.signature.common.utils.PageUtils;
import com.credithc.signature.common.vo.manager.RequestLogVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @desc: <br/>
 * @author: Jingbo Hu<br/>
 * @time：2021年07⽉15⽇<br/>
 * @version：v1.0.0<br>
 */
@RestController
@RequestMapping("/api/signaturePatch/v1")
@Slf4j
public class SignaturePatch {


    @Autowired
    MessageFactory messageFactory;

    @Autowired
    SignatureLogService requestLogService;

    @Autowired
    SignatureLogExtService logExtService;

    @Autowired
    private SignatureLogMapper signatureLogMapper;

    @Autowired
    ChannelService channelService;


    /**
     * 执行重签方法
     *
     * @param requestRo
     * @return
     */
    @PostMapping("/patch")
    public Message patch(@RequestBody RequestLogRo requestRo) {
        // 1、校验必要参数
        boolean result = verifyParams(requestRo);
        if (!result) {
            return messageFactory.getInstance(CoreCodes.CORE_SUCCESS, "|请求地址|渠道号|起始时间|结束时间|缺一不可！");
        }

        // 2、根据参数查询数据
        List<RequestLogVo> dataList = querySigns(requestRo);
        if (CollectionUtils.isEmpty(dataList)) {
            return messageFactory.getInstance(CoreCodes.CORE_SUCCESS, "没有可执行的数据！");
        }

        // 3、发送需要重签的数据
        dataList.stream().forEach(d -> {
            Map<String, String> headers = new HashMap<>();
            JSONObject object = buildPostData(d, headers);

            try {
                String url = requestRo.getUrl();
                HttpClientProxy.post(url, object, headers);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        return messageFactory.getInstance(CoreCodes.CORE_SUCCESS, "执行重签数据量为：" + dataList.size());
    }

    /**
     * 封装发送的数据
     *
     * @param d
     * @param headers
     * @return
     */
    private JSONObject buildPostData(RequestLogVo d, Map<String, String> headers) {
        // 查询渠道和秘钥，并设置请求头
        Channel channel = channelService.selectByChannelNo(d.getChannelNo());
        String encryptKey = channel.getEncryptKey();
        headers.put("Content-Type", "application/json; charset=UTF-8");
        headers.put("encryptKey", encryptKey);

        // 查询请求数据，如果是旧签章请求参数的话改成新签章的请求参数
        Date createTime = d.getCreateTime();
        SignatureLogExt logExt = logExtService.selectOneById(d.getRefId(), DateUtil.getDefaultAppointDateStr(createTime));
        String requestData = logExt.getRequestData();
        if (requestData.contains("singnalElement") || requestData.contains("listElements") || requestData.contains("certApplys")) {
            requestData = requestData.replace("singnalElement", "otherData")
                    .replace("listElements", "listData")
                    .replace("certApplys", "certInfos");
        }

        // 封装请求参数
        JSONObject b = new JSONObject();
        b.put("channelNo", d.getChannelNo());
        b.put("templateNo", d.getTemplateNo());
        b.put("needSign", d.getIsSeal().equals("是") ? true : false);
        b.put("callBackUrl", d.getCallbackUrl());
        b.put("requestData", JSONObject.parseObject(requestData, RequestData.class));
        b.put("encryptKey", encryptKey);
        return b;
    }

    /**
     * 校验参数
     *
     * @param requestRo
     * @return
     */
    private boolean verifyParams(RequestLogRo requestRo) {
        Date startTime = requestRo.getCreateTime();
        Date endTime = requestRo.getUpdateTime();
        String channelNo = requestRo.getChannelNo();
        String url = requestRo.getUrl();
        requestRo.setPageNo(1);
        requestRo.setPageSize(9999);
        if (startTime == null) {
            return false;
        }
        if (endTime == null) {
            return false;
        }
        if (StringUtils.isBlank(channelNo)) {
            return false;
        }
        if (StringUtils.isBlank(url)) {
            return false;
        }
        return true;
    }

    /**
     * 查询数据
     *
     * @param requestLogRo
     * @return
     */
    public List<RequestLogVo> querySigns(RequestLogRo requestLogRo) {
        long startTime = System.currentTimeMillis();
        PageUtils.setPageNo(requestLogRo);
        requestLogRo.setSignStatus(3);
        List<SignatureLog> logPos = signatureLogMapper.querySignatureLogList(requestLogRo);
        List<RequestLogVo> vos = requestLogService.buildPos(logPos);
        log.info(">>>>>>> requestLog 查询耗时 : {}", (System.currentTimeMillis() - startTime));
        return vos;
    }

}
